import WebGl from '@/modules/three';
const { Three } = WebGl;

export interface BlurRadiusType {
  radius?: number;
  blur?: number;
  opacity?: number;
  color1?: string;
  color2?: string;
}

/**
 * 径向模糊材质，并支持双色渐变
 * **/
export class BlurRadiusMaterial extends Three.ShaderMaterial {
  constructor(config: BlurRadiusType) {
    super({
      uniforms: {
        color_1: {
          value: new Three.Color(config.color1 || '#6158db'),
        },
        color_2: {
          value: new Three.Color(config.color2 || config.color1 || '#c23de6'),
        },
        blur_size: {
          value: config.blur || 0.5,
        },
        radius_size: {
          value: config.radius || 0.7,
        },
        opacity: {
          value: config.opacity || 1.0,
        },
      },
      vertexShader: `
          #define GLSLIFY 1
          varying vec2 vUv;
          void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
          }
        `,
      fragmentShader: `
          #define GLSLIFY 1
          /* Easing Sine InOut equation */
          /* Adapted from Robert Penner easing equations */
          #define PI 3.141592653589793
          
          float easeSineInOut(float t) {
            return -0.5 * (cos(PI * t * 2.0) - 1.0);
          }
          
          float circle(in vec2 _uv, in float _radius, in float _blur){
            return 1. - smoothstep(_radius-(_radius*_blur), _radius+(_radius*_blur), dot(_uv,_uv)*4.0);
          }
          
          uniform vec3 color_1;
          uniform vec3 color_2;
          
          uniform float blur_size;
          uniform float radius_size;
          uniform float opacity;
          
          varying vec2 vUv;
          
          mat2 rotate(float _a) {
            return mat2(cos(_a), -sin(_a), sin(_a), cos(_a));
          }
          
          vec2 start = vec2(0.25, 0.8);
          vec2 end   = vec2(0.65, 0.1);
          
          void main() {
            vec2 uv = vUv - 0.5;
        
            float c = circle(uv, radius_size, blur_size);
        
            // Color
            vec2 gDir = end - start;
            float lenSq = dot(gDir, gDir * 0.8);
            vec2 relCoord = uv + 0.5 - start;
            float pct = dot(relCoord, gDir) / lenSq;
        
            vec3 color = mix(color_1, color_2, pct);
            vec4 finalColor = vec4(color, c * opacity);
        
            gl_FragColor = finalColor;
          }
        `,
      transparent: !0,
      // depthFunc: Three.NotEqualDepth,
      side: Three.DoubleSide,
    });
  }
}

/**
 * 边缘辉光材质
 * viewVector 需要实时设置
 * **/
export class LumenSideMaterial extends Three.ShaderMaterial {
  constructor(config: {
    glowColor?: string;
    scale?: number;
    bias?: number;
    power?: number;
    viewVector: any;
  }) {
    super({
      uniforms: {
        glowColor: {
          value: new Three.Color(config.glowColor || '#6158db'),
        },
        bias: {
          value: config.bias || 1.0,
        },
        power: {
          value: config.power || 2.0,
        },
        scale: {
          value: config.scale || -1.0,
        },
        viewVector: {
          value: config.viewVector, //const newView = camera.position.clone().sub(controls.target);
          // customMaterial.uniforms.viewVector.value = newView;
        },
      },
      vertexShader: `
          #define GLSLIFY 1
          uniform vec3 viewVector; // 视角
          varying vec3 vNormal; // 法线
          varying vec3 vPositionNormal;
          void main() {
            vNormal = normalize( normalMatrix * normal ); // 转换到视图空间
            vPositionNormal = normalize(normalMatrix * viewVector);
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
          }
        `,
      fragmentShader: `
          #define GLSLIFY 1
          uniform vec3 glowColor;
          uniform float bias;
          uniform float power;
          uniform float scale;
          varying vec3 vNormal;
          varying vec3 vPositionNormal;
          void main() {
            float a = pow(bias + scale * abs(dot(vNormal, vPositionNormal)), power );
            gl_FragColor = vec4( glowColor, a );
          }
        `,
      transparent: !0,
      side: Three.DoubleSide,
    });
  }
}

// export {

// };
